﻿using Simple3DRedactor.Domain;
using Tao.OpenGl;

namespace Simple3DRedactor.OpenGLViewer
{
    abstract class GeometryView<T> : ObjectView<T> where T : Geometry
    {
        protected GeometryView(T obj, ObjectViewFactory factory)
            : base(obj)
        {
            Id = factory.RegisterNewObject(this);
        }

        public int Id { get; private set; }

        public override void Setup()
        {
        }

        protected override void PreRenderImpl()
        {
            Gl.glColor3f(InnerObject.Material.Diffuse.R / 255.0f, InnerObject.Material.Diffuse.G / 255.0f, InnerObject.Material.Diffuse.B / 255.0f);

            SetupMaterial(Gl.GL_FRONT, InnerObject.Material);

            Gl.glLoadName(Id);
        }

        protected override void PostRenderImpl()
        {
        }

        private static void SetupMaterial(int face, Material m)
        {
            Gl.glMaterialfv(face, Gl.GL_AMBIENT, new[] { m.Ambient.R / 255.0f, m.Ambient.G / 255.0f, m.Ambient.B / 255.0f, m.Ambient.A / 255.0f });
            Gl.glMaterialfv(face, Gl.GL_DIFFUSE, new[] { m.Diffuse.R / 255.0f, m.Diffuse.G / 255.0f, m.Diffuse.B / 255.0f, m.Diffuse.A / 255.0f });
            Gl.glMaterialfv(face, Gl.GL_SPECULAR, new[] { m.Specular.R / 255.0f, m.Specular.G / 255.0f, m.Specular.B / 255.0f, m.Specular.A / 255.0f });
            Gl.glMaterialf(face, Gl.GL_SHININESS, m.Shininess);
            Gl.glMaterialfv(face, Gl.GL_EMISSION, new[] { m.Emission.R / 255.0f, m.Emission.G / 255.0f, m.Emission.B / 255.0f, m.Emission.A / 255.0f });
        }
    }
}
